#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>
#include <strings.h>
#include <cstdio>
#include <errno.h>
#include <functional>
using namespace std;

uint16_t defaultport=8080;//发送信息的端口
const int size=1024;
string defaultip="0.0.0.0";

typedef function<string(string&)> fun_t;   
//fun_c 是个类型，可以装下返回值是string ,参数是string&的仿函数，函数等

class Server
{
public:
    Server(uint16_t port=defaultport,string ip=defaultip)
    :ip_(ip),port_(port),running_(false)
    {}

    void ServerInit()
    {
        sockfd_ = socket(AF_INET, SOCK_DGRAM, 0); // udp,
        if (sockfd_ < 0)
        {
            perror("socket error");
            exit(1);
        }

        struct sockaddr_in local;
        bzero(&local, sizeof(local));

        local.sin_family = AF_INET;
        local.sin_port = htons(port_);
        local.sin_addr.s_addr = inet_addr(ip_.c_str());

        // locl.sim_addr=htonl();

        if (bind(sockfd_, (const struct sockaddr *)&local, sizeof(local)) < 0)
        {
            perror("bind error");
            exit(1);
        }
    }

    void Run(fun_t f)
    {
        running_=true;
        char inbuffer[size];

        while(running_)
        {
            struct sockaddr_in client;//客户端的信息
            socklen_t len=sizeof(client);
            ssize_t n=recvfrom(sockfd_,inbuffer,sizeof(inbuffer)-1,0,(struct sockaddr*)&client,&len);

            if(n<0) continue;                      
                       
                    
            inbuffer[n]=0;

            cout<<inbuffer<<endl;
            string str=inbuffer;
            string info=f(str);//让回调函数处理一下

            sendto(sockfd_,info.c_str(),info.size(),0,(const sockaddr*)&client,len);
        }
    }

private:
    string ip_;
    uint16_t port_;
    int sockfd_;
    bool running_;
};
